<template>
  <!-- 频谱容器 -->
  <div class="spectrum-container" ref="spectrumContainer">
    <template v-if="spectrumType === 'bar'">
      <div v-for="i in spectrumCount" :key="i" class="spectrum-bar" :style="{ height: getBarHeight(i) + 'px' }"></div>
    </template>
    <template v-else-if="spectrumType === 'altBar'">
      <div v-for="i in spectrumCount" :key="i" class="spectrum-bar-alt" :style="{ height: getBarHeight(i) + 'px' }"></div>
    </template>
    <template v-else-if="spectrumType === 'circle'">
      <div v-for="i in spectrumCount" :key="i" class="spectrum-circle" :style="{ transform: 'scale(' + getCircleScale(i) + ')' }"></div>
    </template>
    <template v-else-if="spectrumType === 'grayscale'">
      <div v-for="i in spectrumCount" :key="i" class="spectrum-grayscale" :style="{ height: getBarHeight(i) + 'px', opacity: getGrayscaleOpacity(i) }"></div>
    </template>
    <template v-else-if="spectrumType === 'wave'">
      <div v-for="i in spectrumCount" :key="i" class="spectrum-wave" :style="{ height: getBarHeight(i) + 'px', transform: 'rotate(' + getWaveAngle(i) + 'deg)' }"></div>
    </template>
    <template v-else-if="spectrumType === 'gradient'">
      <div v-for="i in spectrumCount" :key="i" class="spectrum-gradient" :style="{ height: getBarHeight(i) + 'px', background: getGradientColor(i) }"></div>
    </template>
    <template v-else-if="spectrumType === 'pulse'">
      <div v-for="i in spectrumCount" :key="i" class="spectrum-pulse" :style="{ transform: 'scale(' + getPulseScale(i) + ')', opacity: getPulseOpacity(i) }"></div>
    </template>
  </div>
</template>

<script>
export default {
  name: 'AudioSpectrum',
  props: {
    spectrumType: {
      type: String,
      default: 'bar',
      // 频谱类型: 'bar', 'altBar', 'circle'
    },
    audioContext: {
      required: true,
      // 音频上下文对象
      validator: (value) => {
        return value !== null && typeof value === 'object';
      }
    },
    analyserNode: {
      required: true,
      // 音频分析器节点
      validator: (value) => {
        return value !== null && typeof value === 'object';
      }
    }
  },
  data() {
    return {
      spectrumCount: 64, // 频谱数量
      animationFrameId: null, // 动画帧ID
      dataArray: null // 存储频谱数据的数组
    }
  },
  methods: {
    // 初始化频谱
    init() {
      if (!this.analyserNode) return

      // 创建数据数组
      this.dataArray = new Uint8Array(this.analyserNode.frequencyBinCount)
      this.spectrumCount = this.analyserNode.frequencyBinCount

      // 开始动画
      this.animate()
    },

    // 动画循环
    animate() {
      this.animationFrameId = requestAnimationFrame(this.animate)

      if (!this.analyserNode) return

      // 获取频谱数据
      this.analyserNode.getByteFrequencyData(this.dataArray)

      // 触发重新渲染
      this.$forceUpdate()
    },

    // 计算柱状图高度
    getBarHeight(index) {
      if (!this.dataArray) return 0

      // 基于频谱数据计算柱状图高度
      const value = this.dataArray[index]
      return value * 1.5 // 放大值以获得更好的视觉效果
    },

    // 计算圆形缩放比例
  getCircleScale(index) {
    if (!this.dataArray) return 1

    // 基于频谱数据计算圆形缩放
    const value = this.dataArray[index]
    return 1 + (value / 255) * 2 // 缩放范围 1-3
  },

  // 计算灰度不透明度
  getGrayscaleOpacity(index) {
    if (!this.dataArray) return 0.1

    // 基于频谱数据计算不透明度
    const value = this.dataArray[index]
    return 0.1 + (value / 255) * 0.9 // 不透明度范围 0.1-1.0
  },

  // 计算波浪角度
  getWaveAngle(index) {
    if (!this.dataArray) return 0

    // 基于频谱数据计算旋转角度
    const value = this.dataArray[index]
    return (value / 255) * 45 - 22.5 // 角度范围 -22.5° 到 22.5°
  },

  // 获取渐变颜色
  getGradientColor(index) {
    if (!this.dataArray) return 'linear-gradient(to top, #3b82f6, #ec4899)'

    // 根据频率位置生成不同的渐变颜色
    const hue = (index / this.spectrumCount) * 360 // 色相从 0° 到 360°
    return `linear-gradient(to top, hsl(${hue}, 70%, 50%), hsl(${hue}, 90%, 70%))`
  },

  // 计算脉冲缩放
  getPulseScale(index) {
    if (!this.dataArray) return 0.5

    const value = this.dataArray[index]
    return 0.5 + (value / 255) * 1.5 // 缩放范围 0.5-2.0
  },

  // 计算脉冲不透明度
  getPulseOpacity(index) {
    if (!this.dataArray) return 0.3

    const value = this.dataArray[index]
    return 0.3 + (value / 255) * 0.7 // 不透明度范围 0.3-1.0
  }
  },
  // 组件挂载时
  mounted() {
    this.init()
  },

  // 组件销毁前
  beforeDestroy() {
    if (this.animationFrameId) {
      cancelAnimationFrame(this.animationFrameId)
    }
  },

  // 监听属性变化
  watch: {
    // 监听频谱类型变化
    spectrumType() {
      // 当频谱类型改变时，强制重新渲染
      this.$forceUpdate()
    },

    // 监听分析器节点变化
    analyserNode() {
      // 当分析器节点改变时，重新初始化
      if (this.animationFrameId) {
        cancelAnimationFrame(this.animationFrameId)
      }
      this.init()
    }
  }
}
</script>

<style scoped>
.spectrum-grayscale {
  display: inline-block;
  width: 4px;
  margin: 0 1px;
  background: linear-gradient(to top, #000, #888);
  border-radius: 2px;
  vertical-align: bottom;
}

.spectrum-wave {
  display: inline-block;
  width: 6px;
  height: 100px;
  margin: 0 2px;
  background-color: #3b82f6;
  border-radius: 3px;
  vertical-align: middle;
  transition: transform 0.1s ease;
}

.spectrum-gradient {
  display: inline-block;
  width: 8px;
  margin: 0 2px;
  border-radius: 4px;
  vertical-align: bottom;
}

.spectrum-pulse {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin: 0 4px;
  background-color: #f97316;
  border-radius: 50%;
  vertical-align: middle;
  transition: all 0.2s ease;
}

/* 现有样式保持不变 */
.spectrum-bar {
  display: inline-block;
  width: 8px;
  margin: 0 2px;
  background-color: #3b82f6;
  border-radius: 4px;
  vertical-align: bottom;
}

.spectrum-bar-alt {
  display: inline-block;
  width: 2px;
  margin: 0 1px;
  background-color: #ec4899;
  vertical-align: bottom;
}

.spectrum-circle {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin: 0 4px;
  background-color: #10b981;
  border-radius: 50%;
  vertical-align: middle;
}
</style>